home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / Burger.c next >
Text File  |  2000-01-21  |  23KB  |  1,138 lines

  1. /**********************************
  2.  
  3.     Burger library for the Macintosh.
  4.     Use Think.c or Code Warrior to compile.
  5.     Use SMART linking to link in just what you need
  6.  
  7. **********************************/
  8.  
  9. #include "WolfDef.h"        /* Get the prototypes */
  10. #include <string.h>
  11. #include <sound.h>
  12. #include <stdio.h>
  13. #include <palettes.h>
  14. #include "SoundMusicSystem.h"
  15. #include "PickAMonitor.h"
  16.  
  17. /**********************************
  18.  
  19.     Variables used by my global library
  20.  
  21. **********************************/
  22.  
  23. Word DoEvent(EventRecord *event);
  24. void DoMacEvents(void);
  25. void BlastScreen(void);
  26. static Word FreeStage(Word Stage,LongWord Size);
  27.  
  28. extern Boolean MouseHit;        /* True if a mouse down event occured */
  29. Word NoSystemMem;
  30. unsigned char *VideoPointer;    /* Pointer to video memory */
  31. extern Word QuitFlag;            /* Did the application quit? */
  32. Word VideoWidth;                /* Width to each video scan line */
  33. Word SystemState=3;                /* Sound on/off flags */
  34. Word KilledSong;                /* Song that's currently playing */
  35. Word KeyModifiers;                /* Keyboard modifier flags */
  36. LongWord LastTick;                /* Last system tick (60hz) */
  37. Word FontX;                        /* X Coord of font */
  38. Word FontY;                        /* Y Coord of font */
  39. unsigned char *FontPtr;            /* Pointer to font image data */
  40. unsigned char *FontWidths;        /* Pointer to font width table */
  41. Word FontHeight;                /* Point size of current font */
  42. Word FontLast;                    /* Number of font entries */
  43. Word FontFirst;                    /* ASCII value of first char */
  44. Word FontLoaded;                /* Rez number of loaded font (0 if none) */
  45. Word FontInvisible;                /* Allow masking? */
  46. unsigned char FontOrMask[16];    /* Colors for font */
  47. LongWord YTable[480];            /* Offsets to the screen */
  48. SndChannelPtr myPaddleSndChan;    /* Sound channel */
  49. Word ScanCode;
  50. CWindowPtr GameWindow;
  51. CGrafPtr GameGWorld;
  52. extern GDHandle gMainGDH;
  53. extern CTabHandle MainColorHandle;
  54. extern Boolean DoQuickDraw;
  55.  
  56. /**********************************
  57.  
  58.     Wait a single system tick
  59.  
  60. **********************************/
  61.  
  62. static Word QuickTicker;
  63.  
  64. void DoMacEvents(void)
  65. {
  66.     EventRecord MyEvent;
  67.     if (!DoQuickDraw) {
  68.         if ((ReadTick() - QuickTicker) < 30) {
  69.             return;
  70.         }
  71.         QuickTicker = ReadTick();
  72.     }
  73.     PurgeAllSounds(85000);        /* Try to keep some memory free */
  74.     if (WaitNextEvent2(updateMask|diskMask|driverMask|networkMask|activMask|app4Mask,&MyEvent,0,0)) {
  75.         DoEvent(&MyEvent);
  76.     }
  77. }
  78.  
  79. /**********************************
  80.  
  81.     Wait a single system tick
  82.  
  83. **********************************/
  84.  
  85. void WaitTick(void)
  86. {
  87.     do {
  88.         DoMacEvents();            /* Allow backgrounding */
  89.     } while (ReadTick()==LastTick);    /* Tick changed? */
  90.     LastTick=ReadTick();        /* Save it */
  91. }
  92.  
  93. /**********************************
  94.  
  95.     Wait a specific number of system ticks
  96.     from a time mark before you get control
  97.  
  98. **********************************/
  99.  
  100. void WaitTicks(Word Count)
  101. {
  102.     LongWord TickMark;        /* Temp tick mark */
  103.     
  104.     do {
  105.         DoMacEvents();        /* Allow other tasks to execute */
  106.         TickMark = ReadTick();    /* Get the mark */
  107.     } while ((TickMark-LastTick)<=Count);    /* Time up? */
  108.     LastTick = TickMark;    /* Save the new time mark */
  109. }
  110.  
  111. /**********************************
  112.  
  113.     Get the current system tick
  114.  
  115. **********************************/
  116.  
  117. LongWord ReadTick(void)
  118. {
  119.     return(TickCount());    /* Just get it from the Mac OS */
  120. }
  121.  
  122. /**********************************
  123.  
  124.     Wait for a mouse/keyboard event
  125.  
  126. **********************************/
  127.  
  128. Word WaitEvent(void)
  129. {
  130.     Word Temp;
  131.     do {
  132.         Temp = WaitTicksEvent(6000);    /* Wait 10 minutes */
  133.     } while (!Temp);    /* No event? */
  134.     return Temp;        /* Return the event code */
  135. }
  136.  
  137. /**********************************
  138.  
  139.     Wait for an event or a timeout
  140.  
  141. **********************************/
  142.  
  143. Word WaitTicksEvent(Word Time)
  144. {
  145.     LongWord TickMark;
  146.     LongWord NewMark;
  147.     Word RetVal;
  148.  
  149.     MouseHit = FALSE;
  150.     TickMark = ReadTick();    /* Get the initial time mark */
  151.     for (;;) {
  152.         DoMacEvents();        /* Allow other tasks a shot! */
  153.         NewMark = ReadTick();        /* Get the new time mark */
  154.         if (Time) {
  155.             if ((NewMark-TickMark)>=Time) {    /* Time up? */
  156.                 RetVal = 0;    /* Return timeout */
  157.                 break;
  158.             }
  159.         }
  160.         RetVal = GetAKey();
  161.         if (RetVal) {
  162.             break;
  163.         }
  164.         if (MouseHit) {
  165.             RetVal = 1;        /* Hit the mouse */
  166.             break;
  167.         }
  168.     }
  169.     LastTick = NewMark;
  170.     return RetVal;
  171. }
  172.  
  173. /**********************************
  174.  
  175.     Get a key from the keyboard
  176.  
  177. **********************************/
  178.  
  179. Word GetAKey(void)
  180. {
  181.     EventRecord MyRecord;
  182.  
  183.     if (WaitNextEvent2(everyEvent,&MyRecord,0,0)) {
  184.         if (!DoEvent(&MyRecord)) {
  185.             KeyModifiers = MyRecord.modifiers;
  186.             return 0;
  187.         }
  188.         return FixMacKey(&MyRecord);
  189.     }
  190.     return 0;
  191. }
  192.  
  193. /**********************************
  194.  
  195.     Check if all keys are released
  196.  
  197. **********************************/
  198.  
  199. Word WaitKey(void)
  200. {
  201.     Word Key;
  202.     do {
  203.         Key = GetAKey();
  204.     } while (!Key);
  205.     return (Key);
  206. }
  207.  
  208. /**********************************
  209.  
  210.     Check if all keys are released
  211.  
  212. **********************************/
  213.  
  214. Word AllKeysUp(void)
  215. {
  216.     KeyMap KeyArray;
  217.  
  218.     GetKeys(KeyArray);
  219.     if (KeyArray[0] || KeyArray[1] || KeyArray[2] || KeyArray[3]) {
  220.         return 0;
  221.     }
  222.     return 1;
  223. }
  224.  
  225. Word FixMacKey(EventRecord *Event)
  226. {
  227.     Word NewKey;
  228.     NewKey = Event->message & 0xff;
  229.     ScanCode = (Event->message>>8) & 0xff;
  230.     switch (NewKey) {
  231.     case 0x1c :
  232.         NewKey = 0x08;
  233.         break;
  234.     case 0x1d :
  235.         NewKey = 0x15;
  236.         break;
  237.     case 0x1e :
  238.         NewKey = 0x0b;
  239.         break;
  240.     case 0x1f :
  241.         NewKey = 0x0a;
  242.         break;
  243.     }
  244.     KeyModifiers = Event->modifiers;
  245.     if (NewKey == 'Q' || NewKey == 'q') {
  246.         if (KeyModifiers & cmdKey) {
  247.             QuitFlag = 1;
  248.         }
  249.     }
  250.     return NewKey;
  251. }    
  252.             
  253. /**********************************
  254.  
  255.     Flush out the keyboard buffer
  256.  
  257. **********************************/
  258.  
  259. void FlushKeys(void)
  260. {
  261.     while (GetAKey()) {}
  262. }
  263.  
  264. /**********************************
  265.  
  266.     Convert a long value into a ascii string
  267.  
  268. **********************************/
  269.  
  270. static LongWord Tens[] = {
  271.     1,
  272.     10,
  273.     100,
  274.     1000,
  275.     10000,
  276.     100000,
  277.     1000000,
  278.     10000000,
  279.     100000000,
  280.     1000000000};
  281.  
  282. void ultoa(LongWord Val,char *Text)
  283. {
  284.     Word Index;        /* Index to Tens table */
  285.     Word Hit;        /* Printing? */
  286.     Word Letter;    /* Letter to print */
  287.     LongWord LongVal;    /* Tens value */
  288.  
  289.     Index = 9;        /* Start at the millions */
  290.     Hit = 0;        /* Didn't print anything yet! */
  291.     do {
  292.         Letter = '0';    /* Init the char */
  293.         LongVal = Tens[Index];    /* Init the value into a local */
  294.         while (Val >= LongVal) {    /* Is the number in question larger? */
  295.             Val -= LongVal;        /* Sub the tens value */
  296.             ++Letter;            /* Inc the char */
  297.             Hit=1;                /* I must draw! */
  298.         }
  299.         if (Hit) {    /* Remove the leading zeros */
  300.             Text[0] = Letter;    /* Save char in the string */
  301.             ++Text;            /* Inc dest */
  302.         }
  303.     } while (--Index);        /* All the tens done? */
  304.     Text[0] = Val + '0';    /* Must print FINAL digit */
  305.     Text[1] = 0;            /* End the string */
  306. }
  307.  
  308. /**********************************
  309.  
  310.     Sound sub-system
  311.  
  312. **********************************/
  313.  
  314. /**********************************
  315.  
  316.     Shut down the sound
  317.  
  318. **********************************/
  319.  
  320. void SoundOff(void)
  321. {
  322.     PlaySound(0);
  323. }
  324.  
  325. /**********************************
  326.  
  327.     Play a sound resource
  328.  
  329. **********************************/
  330.  
  331. void PlaySound(Word SoundNum)
  332. {
  333.     if (SoundNum && (SystemState&SfxActive)) {
  334.         SoundNum+=127;
  335.         if (SoundNum&0x8000) {        /* Mono sound */
  336.             EndSound(SoundNum&0x7fff);
  337.         }
  338.         BeginSound(SoundNum&0x7fff,11127<<17L);
  339.     } else {
  340.         EndAllSound();
  341.     }
  342. }
  343.  
  344. /**********************************
  345.  
  346.     Stop playing a sound resource
  347.  
  348. **********************************/
  349.  
  350. void StopSound(Word SoundNum)
  351. {
  352.     EndSound(SoundNum+127);
  353. }
  354.  
  355. static Word LastSong = -1;
  356.  
  357. void PlaySong(Word Song)
  358. {
  359.     if (Song) {
  360.         KilledSong = Song;
  361.         if (SystemState&MusicActive) {
  362.             if (Song!=LastSong) {
  363.                 BeginSongLooped(Song);    
  364.                 LastSong = Song;
  365.             }
  366.             return;
  367.         }
  368.     } 
  369.     EndSong();
  370.     LastSong = -1;
  371. }
  372.  
  373. /**********************************
  374.  
  375.     Graphics subsystem
  376.  
  377. **********************************/
  378.  
  379. /**********************************
  380.  
  381.     Draw a masked shape
  382.  
  383. **********************************/
  384.  
  385. void InitYTable(void)
  386. {
  387.     Word i;
  388.     LongWord Offset;
  389.  
  390.     i = 0;
  391.     Offset = 0;
  392.     do {
  393.         YTable[i] = Offset;
  394.         Offset+=VideoWidth;
  395.     } while (++i<480);
  396. }
  397.  
  398. /**********************************
  399.  
  400.     Draw a shape
  401.  
  402. **********************************/
  403.  
  404. void DrawShape(Word x,Word y,void *ShapePtr)
  405. {
  406.     unsigned char *ScreenPtr;
  407.     unsigned char *Screenad;
  408.     unsigned char *ShapePtr2;
  409.     unsigned short *ShapePtr3;
  410.     Word Width;
  411.     Word Height;
  412.     Word Width2;
  413.  
  414.     ShapePtr3 = ShapePtr;
  415.     Width = ShapePtr3[0];        /* 16 bit width */
  416.     Height = ShapePtr3[1];        /* 16 bit height */
  417.     ShapePtr2 = (unsigned char *) &ShapePtr3[2];
  418.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
  419.     do {
  420.         Width2 = Width;
  421.         Screenad = ScreenPtr;
  422.         do {
  423.             *Screenad++ = *ShapePtr2++;
  424.         } while (--Width2);
  425.         ScreenPtr +=VideoWidth;
  426.     } while (--Height);
  427. }
  428.  
  429. /**********************************
  430.  
  431.     Draw a masked shape
  432.  
  433. **********************************/
  434.  
  435. void DrawMShape(Word x,Word y,void *ShapePtr)
  436. {
  437.     unsigned char *ScreenPtr;
  438.     unsigned char *Screenad;
  439.     unsigned char *MaskPtr;
  440.     unsigned char *ShapePtr2;
  441.     Word Width;
  442.     Word Height;
  443.     Word Width2;
  444.  
  445.     ShapePtr2 = ShapePtr;
  446.     Width = ShapePtr2[1];
  447.     Height = ShapePtr2[3];
  448.     ShapePtr2 +=4;
  449.     MaskPtr = &ShapePtr2[Width*Height];
  450.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
  451.     do {
  452.         Width2 = Width;
  453.         Screenad = ScreenPtr;
  454.         do {
  455.             *Screenad = (*Screenad & *MaskPtr++) | *ShapePtr2++;
  456.             ++Screenad;
  457.         } while (--Width2);
  458.         ScreenPtr +=VideoWidth;
  459.     } while (--Height);
  460. }
  461.  
  462. /**********************************
  463.  
  464.     Draw a masked shape with an offset
  465.  
  466. **********************************/
  467.  
  468. void DrawXMShape(Word x,Word y,void *ShapePtr)
  469. {
  470.     unsigned short *ShapePtr2;
  471.     ShapePtr2 = ShapePtr;
  472.     x += ShapePtr2[0];
  473.     y += ShapePtr2[1];
  474.     DrawMShape(x,y,&ShapePtr2[2]);
  475. }
  476.  
  477. /**********************************
  478.  
  479.     Erase a masked shape
  480.  
  481. **********************************/
  482.  
  483. void EraseMBShape(Word x,Word y, void *ShapePtr, void *BackPtr)
  484. {
  485.     unsigned char *ScreenPtr;
  486.     unsigned char *Screenad;
  487.     unsigned char *Backad;
  488.     unsigned char *BackPtr2;
  489.     unsigned char *MaskPtr;
  490.     Word Width;
  491.     Word Height;
  492.     Word Width2;
  493.  
  494.     MaskPtr = ShapePtr;        /* Get the pointer to the mask */
  495.     Width = MaskPtr[1];        /* Get the width of the shape */
  496.     Height = MaskPtr[3];    /* Get the height of the shape */
  497.     MaskPtr = &MaskPtr[(Width*Height)+4];    /* Index to the mask */
  498.                             /* Point to the screen */
  499.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
  500.     BackPtr2 = BackPtr;
  501.     BackPtr2 = &BackPtr2[(y*SCREENWIDTH)+x];    /* Index to the erase buffer */
  502.     do {
  503.         Width2 = Width;        /* Init width count */
  504.         Screenad = ScreenPtr;
  505.         Backad = BackPtr2;
  506.         do {
  507.             if (!*MaskPtr++) {
  508.                 *Screenad = *Backad;
  509.             }
  510.             ++Screenad;
  511.             ++Backad;
  512.         } while (--Width2);
  513.         ScreenPtr +=VideoWidth;
  514.         BackPtr2 += SCREENWIDTH;
  515.     } while (--Height);
  516. }
  517.  
  518. /**********************************
  519.  
  520.     Test for a shape collision
  521.  
  522. **********************************/
  523.  
  524. Word TestMShape(Word x,Word y,void *ShapePtr)
  525. {
  526.     unsigned char *ScreenPtr;
  527.     unsigned char *Screenad;
  528.     unsigned char *MaskPtr;
  529.     unsigned char *ShapePtr2;
  530.     Word Width;
  531.     Word Height;
  532.     Word Width2;
  533.  
  534.     ShapePtr2 = ShapePtr;
  535.     Width = ShapePtr2[0];
  536.     Height = ShapePtr2[1];
  537.     ShapePtr2 +=2;
  538.     MaskPtr = &ShapePtr2[Width*Height];
  539.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
  540.     do {
  541.         Width2 = Width;
  542.         Screenad = ScreenPtr;
  543.         do {
  544.             if (!*MaskPtr++) {
  545.                 if (*Screenad != *ShapePtr2) {
  546.                     return 1;
  547.                 }
  548.             }
  549.             ++ShapePtr2;
  550.             ++Screenad;
  551.         } while (--Width2);
  552.         ScreenPtr +=VideoWidth;
  553.     } while (--Height);
  554.     return 0;
  555. }
  556.  
  557. /**********************************
  558.  
  559.     Test for a masked shape collision
  560.  
  561. **********************************/
  562.  
  563. Word TestMBShape(Word x,Word y,void *ShapePtr,void *BackPtr)
  564. {
  565.     unsigned char *ScreenPtr;
  566.     unsigned char *Screenad;
  567.     unsigned char *Backad;
  568.     unsigned char *BackPtr2;
  569.     unsigned char *MaskPtr;
  570.     Word Width;
  571.     Word Height;
  572.     Word Width2;
  573.  
  574.     MaskPtr = ShapePtr;        /* Get the pointer to the mask */
  575.     Width = MaskPtr[0];        /* Get the width of the shape */
  576.     Height = MaskPtr[1];    /* Get the height of the shape */
  577.     MaskPtr = &MaskPtr[(Width*Height)+2];    /* Index to the mask */
  578.                             /* Point to the screen */
  579.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
  580.     BackPtr2 = BackPtr;
  581.     BackPtr2 = &BackPtr2[(y*SCREENWIDTH)+x];    /* Index to the erase buffer */
  582.     do {
  583.         Width2 = Width;        /* Init width count */
  584.         Screenad = ScreenPtr;
  585.         Backad = BackPtr2;
  586.         do {
  587.             if (!*MaskPtr++) {
  588.                 if (*Screenad != *Backad) {
  589.                     return 1;
  590.                 }
  591.             }
  592.             ++Screenad;
  593.             ++Backad;
  594.         } while (--Width2);
  595.         ScreenPtr +=VideoWidth;
  596.         BackPtr2 += SCREENWIDTH;
  597.     } while (--Height);
  598.     return 0;
  599. }
  600.  
  601. /**********************************
  602.  
  603.     Show a full screen picture
  604.  
  605. **********************************/
  606.  
  607. void ShowPic(Word PicNum)
  608. {
  609.     DrawShape(0,0,LoadAResource(PicNum));    /* Load the resource and show it */
  610.     ReleaseAResource(PicNum);            /* Release it */
  611.     BlastScreen();
  612. }
  613.  
  614. /**********************************
  615.  
  616.     Clear the screen to a specific color
  617.  
  618. **********************************/
  619.  
  620. void ClearTheScreen(Word Color)
  621. {
  622.     Word x,y;
  623.     unsigned char *TempPtr;
  624.  
  625.     TempPtr = VideoPointer;
  626.     y = SCREENHEIGHT;        /* 200 lines high */
  627.     do {
  628.         x = 0;
  629.         do {
  630.             TempPtr[x] = Color;    /* Fill color */
  631.         } while (++x<SCREENWIDTH);
  632.         TempPtr += VideoWidth;    /* Next line down */
  633.     } while (--y);
  634. }
  635.  
  636. /**********************************
  637.  
  638.     Draw a text string
  639.  
  640. **********************************/
  641.  
  642. void DrawAString(char *TextPtr)
  643. {
  644.     while (TextPtr[0]) {        /* At the end of the string? */
  645.         DrawAChar(TextPtr[0]);    /* Draw the char */
  646.         ++TextPtr;            /* Continue */
  647.     }
  648. }
  649.  
  650. /**********************************
  651.  
  652.     Set the X/Y to the font system
  653.  
  654. **********************************/
  655.  
  656. void SetFontXY (Word x,Word y)
  657. {
  658.     FontX = x;
  659.     FontY = y;
  660. }
  661.  
  662. /**********************************
  663.  
  664.     Make color zero invisible
  665.  
  666. **********************************/
  667.  
  668. void FontUseMask(void)
  669. {
  670.     FontInvisible = 0;
  671.     FontSetColor(0,0);
  672. }
  673.  
  674. /**********************************
  675.  
  676.     Make color zero a valid color
  677.  
  678. **********************************/
  679.  
  680. void FontUseZero(void)
  681. {
  682.     FontInvisible = -1;
  683.     FontSetColor(0,BLACK);
  684. }
  685.  
  686. /**********************************
  687.  
  688.     Set the color entry for the font
  689.  
  690. **********************************/
  691.  
  692. void FontSetColor(Word Num,Word Color)
  693. {
  694.     FontOrMask[Num] = Color;
  695. }
  696.  
  697. /**********************************
  698.  
  699.     Install a font into memory
  700.  
  701. **********************************/
  702.  
  703. typedef struct FontStruct {
  704.     unsigned short FHeight;
  705.     unsigned short FLast;
  706.     unsigned short FFirst;
  707.     unsigned char FData;
  708. } FontStruct;
  709.  
  710. void InstallAFont(Word FontNum)
  711. {
  712.     FontStruct *FPtr;
  713.  
  714.     if (FontLoaded) {
  715.         if (FontLoaded == FontNum) {
  716.             return;
  717.         }
  718.         ReleaseAResource(FontLoaded);
  719.     }
  720.     FontLoaded = FontNum;
  721.     FPtr = LoadAResource(FontNum);
  722.     FontHeight = SwapUShort(FPtr->FHeight);
  723.     FontLast = SwapUShort(FPtr->FLast);
  724.     FontFirst = SwapUShort(FPtr->FFirst);
  725.     FontWidths = &FPtr->FData;
  726.     FontPtr = &FontWidths[FontLast];
  727. }
  728.  
  729. /**********************************
  730.  
  731.     Draw a char to the screen
  732.  
  733. **********************************/
  734.  
  735. void DrawAChar(Word Letter)
  736. {
  737.     Word XWidth;
  738.     Word Offset;
  739.     Word Width;
  740.     Word Height;
  741.     int Width2;
  742.     unsigned char *Font;
  743.     unsigned char *ScreenPtr;
  744.     unsigned char *Screenad;
  745.     unsigned char *FontOr;
  746.     Word Temp;
  747.     Word Temp2;
  748.  
  749.     Letter -= FontFirst;        /* Offset from the first entry */
  750.     if (Letter>=FontLast) {        /* In the font? */
  751.         return;                    /* Exit then! */
  752.     }
  753.     XWidth = FontWidths[Letter];    /* Get the pixel width of the entry */
  754.     Width = (XWidth-1)/2;
  755.     Font = &FontPtr[Letter*2];
  756.     Offset = (Font[1]*256) + Font[0];
  757.     Font = &FontPtr[Offset];
  758.     ScreenPtr = (unsigned char *) &VideoPointer[YTable[FontY]+FontX];
  759.     FontX+=XWidth;
  760.     Height = FontHeight;
  761.     FontOr = &FontOrMask[0];
  762.  
  763.     do {
  764.         Screenad = ScreenPtr;
  765.         Width2 = Width;
  766.         do {
  767.             Temp = *Font++;
  768.             Temp2 = Temp>>4;
  769.             if (Temp2 != FontInvisible) {
  770.                 Screenad[0] = FontOr[Temp2];
  771.             }
  772.             Temp &= 0x0f;
  773.             if (Temp != FontInvisible) {
  774.                 Screenad[1] = FontOr[Temp];
  775.             }
  776.             Screenad+=2;        /* Next address */
  777.         } while(--Width2>=0);
  778.         ScreenPtr += VideoWidth;
  779.     } while (--Height);
  780. }
  781.  
  782. /**********************************
  783.  
  784.     Palette Manager
  785.  
  786. **********************************/
  787.  
  788. /**********************************
  789.  
  790.     Load and set a palette resource
  791.  
  792. **********************************/
  793.  
  794. void SetAPalette(Word PalNum)
  795. {
  796.     SetAPalettePtr(LoadAResource(PalNum));        /* Set the current palette */
  797.     ReleaseAResource(PalNum);                    /* Release the resource */
  798. }
  799.  
  800. /**********************************
  801.  
  802.     Load and set a palette from a pointer
  803.  
  804. **********************************/
  805.  
  806. Byte CurrentPal[768];
  807.  
  808. void SetAPalettePtr(unsigned char *PalPtr)
  809. {
  810.     CTabHandle ColorHandle;        /* Handle to the main palette */
  811.     Handle PalHand;            /* Handle to palette */
  812.     Word i;                    /* Temp */
  813.     CSpecArray *Colors;        /* Pointer to color array */
  814.     GDHandle OldDevice;
  815.     
  816.     memcpy(CurrentPal,PalPtr,768);
  817.     ColorHandle = MainColorHandle;
  818.     HLock((Handle) ColorHandle);
  819.     Colors = &(*ColorHandle)->ctTable;
  820.     ++Colors;        /* Go to color #0 */
  821.     i = 1;            /* Skip color #0 */
  822.     PalPtr+=3;
  823.     do {            /* Fill in all the color entries */
  824.         Colors[0]->rgb.red = (Word) (PalPtr[0]<<8) | PalPtr[0];
  825.         Colors[0]->rgb.green = (Word) (PalPtr[1]<<8) | PalPtr[1];
  826.         Colors[0]->rgb.blue = (Word) (PalPtr[2]<<8) | PalPtr[2];
  827.         if (!Colors[0]->rgb.blue) {
  828.             Colors[0]->rgb.blue = 0x0101;
  829.         }
  830.         PalPtr+=3;
  831.         ++Colors;
  832.     } while (++i<255);    /* All done? */
  833.     OldDevice = GetGDevice();
  834.     SetGDevice(gMainGDH);
  835.     SetEntries(0,255-1,(*ColorHandle)->ctTable);    /* Set the color entries */
  836.     PalHand = (Handle) (**(*GameGWorld).portPixMap).pmTable;
  837.     PtrToXHand(*ColorHandle,PalHand,8+(8*256));
  838.     PalHand = (Handle) (**(*GameWindow).portPixMap).pmTable;
  839.     PtrToXHand(*ColorHandle,PalHand,8+(8*256));
  840.     HUnlock((Handle)ColorHandle);    /* Release the main handle */
  841.     MakeITable(0,0,0);                /* Create the proper color table */
  842.     SetGDevice(OldDevice);
  843. }
  844.  
  845. /**********************************
  846.  
  847.     Fade the screen to black
  848.  
  849. **********************************/
  850.  
  851. void FadeToBlack(void)
  852. {
  853.     unsigned char MyPal[768];
  854.  
  855.     memset(MyPal,0,sizeof(MyPal));    /* Fill with black */
  856.     MyPal[0] = MyPal[1] = MyPal[2] = 255;
  857.     FadeToPtr(MyPal);
  858. }
  859.  
  860. /**********************************
  861.  
  862.     Fade the screen to a palette
  863.  
  864. **********************************/
  865.  
  866. void FadeTo(Word RezNum)
  867. {
  868.     FadeToPtr(LoadAResource(RezNum));
  869.     ReleaseAResource(RezNum);
  870. }
  871.  
  872. /**********************************
  873.  
  874.     Fade the palette
  875.  
  876. **********************************/
  877.  
  878. void FadeToPtr(unsigned char *PalPtr)
  879. {
  880.     int DestPalette[768];                /* Dest offsets */
  881.     Byte WorkPalette[768];        /* Palette to draw */
  882.     Byte SrcPal[768];
  883.     Word Count;
  884.     Word i;
  885.     
  886.     if (!memcmp(PalPtr,&CurrentPal,768)) {    /* Same palette? */
  887.         return;
  888.     }
  889.     memcpy(SrcPal,CurrentPal,768);
  890.     i = 0;
  891.     do {        /* Convert the source palette to ints */
  892.         DestPalette[i] = PalPtr[i];            
  893.     } while (++i<768);
  894.  
  895.     i = 0;
  896.     do {
  897.         DestPalette[i] -= SrcPal[i];    /* Convert to delta's */
  898.     } while (++i<768);
  899.  
  900.     Count = 1;
  901.     do {
  902.         i = 0;
  903.         do {
  904.             WorkPalette[i] = ((DestPalette[i] * (int)(Count)) / 16) + SrcPal[i];
  905.         } while (++i<768);
  906.         SetAPalettePtr(WorkPalette);
  907.         WaitTicks(1);
  908.     } while (++Count<17);
  909. }
  910.  
  911. /**********************************
  912.  
  913.     Resource manager subsystem
  914.  
  915. **********************************/
  916.  
  917. /**********************************
  918.  
  919.     Load a personal resource
  920.  
  921. **********************************/
  922.  
  923. void *LoadAResource(Word RezNum) 
  924. {
  925.     return(LoadAResource2(RezNum,'BRGR'));
  926. }
  927.  
  928. /**********************************
  929.  
  930.     Load a global resource
  931.  
  932. **********************************/
  933.  
  934. Handle RezHandle;
  935.  
  936. void *LoadAResource2(Word RezNum,LongWord Type)
  937. {
  938.     Handle MyHand;
  939.     Word Stage;
  940.     
  941.     Stage = 0;
  942.     do {
  943.         Stage = FreeStage(Stage,128000);
  944.         MyHand = GetResource(Type,RezNum);
  945.         if (MyHand) {
  946.             RezHandle = MyHand;
  947.             HLock(MyHand);
  948.             return *MyHand;
  949.         }
  950.     } while (Stage);
  951.     return 0;
  952. }
  953.  
  954. /**********************************
  955.  
  956.     Allow a resource to be purged
  957.  
  958. **********************************/
  959.  
  960. void ReleaseAResource(Word RezNum)
  961. {
  962.     ReleaseAResource2(RezNum,'BRGR');
  963. }
  964.  
  965. /**********************************
  966.  
  967.     Release a global resource
  968.  
  969. **********************************/
  970.  
  971. void ReleaseAResource2(Word RezNum,LongWord Type)
  972. {
  973.     Handle MyHand;
  974.     
  975.     MyHand = GetResource(Type,RezNum);    /* Get the resource if available */
  976.     HUnlock(MyHand);    
  977.     HPurge(MyHand);            /* Mark handle as purgeable */
  978. }
  979.  
  980. /**********************************
  981.  
  982.     Force a resource to be destroyed
  983.  
  984. **********************************/
  985.  
  986. void KillAResource(Word RezNum)
  987. {
  988.     KillAResource2(RezNum,'BRGR');
  989. }
  990.  
  991. /**********************************
  992.  
  993.     Kill a global resource
  994.  
  995. **********************************/
  996.  
  997. void KillAResource2(Word RezNum,LongWord Type)
  998. {
  999.     Handle MyHand;
  1000.     MyHand = GetResource(Type,RezNum);    /* Get the resource if available */
  1001.     ReleaseResource(MyHand);
  1002. }
  1003.  
  1004. void SaveJunk(void *AckPtr,Word Length)
  1005. {
  1006. static Word Count=1;
  1007.     FILE *fp;
  1008.     char SaveName[40];
  1009.     sprintf(SaveName,"SprRec%d",Count);
  1010.     fp = fopen(SaveName,"wb");
  1011.     fwrite(AckPtr,1,Length,fp);
  1012.     fclose(fp);
  1013.     ++Count;
  1014. }
  1015.  
  1016. /**********************************
  1017.  
  1018.     Kill a global resource
  1019.  
  1020. **********************************/
  1021.  
  1022. unsigned short SwapUShort(unsigned short Val)
  1023. {
  1024.     return ((Val<<8) | (Val>>8));
  1025. }
  1026.  
  1027. /**********************************
  1028.  
  1029.     Decompress using LZSS
  1030.  
  1031. **********************************/
  1032.  
  1033. #if 1
  1034. void DLZSS(Byte *Dest,Byte *Src,LongWord Length)
  1035. {
  1036.     Word BitBucket;
  1037.     Word RunCount;
  1038.     Word Fun;
  1039.     Byte *BackPtr;
  1040.     
  1041.     if (!Length) {
  1042.         return;
  1043.     }
  1044.     BitBucket = (Word) Src[0] | 0x100;
  1045.     ++Src;
  1046.     do {
  1047.         if (BitBucket&1) {
  1048.             Dest[0] = Src[0];
  1049.             ++Src;
  1050.             ++Dest;
  1051.             --Length;
  1052.         } else {
  1053.             RunCount = (Word) Src[0] | ((Word) Src[1]<<8);
  1054.             Fun = 0x1000-(RunCount&0xfff);
  1055.             BackPtr = Dest-Fun;
  1056.             RunCount = ((RunCount>>12) & 0x0f) + 3;
  1057.             if (Length >= RunCount) {
  1058.                 Length -= RunCount;
  1059.             } else {
  1060.                 Length = 0;
  1061.             }
  1062.             do {
  1063.                 *Dest++ = *BackPtr++;
  1064.             } while (--RunCount);
  1065.             Src+=2;
  1066.         }
  1067.         BitBucket>>=1;
  1068.         if (BitBucket==1) {
  1069.             BitBucket = (Word)Src[0] | 0x100;
  1070.             ++Src;
  1071.         }
  1072.     } while (Length);
  1073. }
  1074. #endif
  1075.  
  1076. /**********************************
  1077.  
  1078.     Allocate some memory
  1079.  
  1080. **********************************/
  1081.  
  1082. void *AllocSomeMem(LongWord Size)
  1083. {
  1084.     void *MemPtr;
  1085.     Word Stage;
  1086.     
  1087.     Stage = 0;
  1088.     do {
  1089.         Stage = FreeStage(Stage,Size);
  1090.         MemPtr = NewPtr(Size);        /* Get some memory */
  1091.         if (MemPtr) {
  1092.             return MemPtr;            /* Return it */
  1093.         }
  1094.     } while (Stage);
  1095.     if (!NoSystemMem) {
  1096.         MemPtr = NewPtrSys(Size);
  1097.     }
  1098.     return MemPtr;
  1099. }
  1100.  
  1101. /**********************************
  1102.  
  1103.     Allocate some memory
  1104.  
  1105. **********************************/
  1106.  
  1107. static Word FreeStage(Word Stage,LongWord Size) 
  1108. {
  1109.     switch (Stage) {
  1110.     case 1:
  1111.         PurgeAllSounds(Size);        /* Kill off sounds until I can get memory */
  1112.         break;
  1113.     case 2:
  1114.         PlaySound(0);                /* Shut down all sounds... */
  1115.         PurgeAllSounds(Size);        /* Purge them */
  1116.         break;
  1117.     case 3:
  1118.         PlaySong(0);                /* Kill music */
  1119.         FreeSong();                    /* Purge it */
  1120.         PurgeAllSounds(Size);        /* Make SURE it's gone! */
  1121.         break;
  1122.     case 4:
  1123.         return 0;
  1124.     }
  1125.     return Stage+1;
  1126. }
  1127.  
  1128. /**********************************
  1129.  
  1130.     Release some memory
  1131.  
  1132. **********************************/
  1133.  
  1134. void FreeSomeMem(void *MemPtr)
  1135. {
  1136.     DisposePtr(MemPtr);
  1137. }
  1138.